package com.zang.blogz.service.impl;

import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.stp.StpInterface;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zang.blogz.constant.RedisConstant;
import com.zang.blogz.entity.Resource;
import com.zang.blogz.entity.Role;
import com.zang.blogz.entity.RoleResource;
import com.zang.blogz.mapper.RoleResourceMapper;
import com.zang.blogz.service.RedisService;
import com.zang.blogz.service.ResourceService;
import com.zang.blogz.service.RoleResourceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zang.blogz.service.RoleService;
import io.github.vampireachao.stream.core.optional.Opp;
import io.github.vampireachao.stream.plugin.mybatisplus.Many;

import io.github.vampireachao.stream.plugin.mybatisplus.One;
import io.github.vampireachao.stream.plugin.mybatisplus.OneToMany;
import io.github.vampireachao.stream.plugin.mybatisplus.OneToManyToOne;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 朵橙i
 * @since 2022-06-17
 */
@Service
public class RoleResourceServiceImpl extends ServiceImpl<RoleResourceMapper, RoleResource> implements RoleResourceService {

    @Autowired
    private RedisService redisService;

    /**
     * @return 得到当前登录的用户所拥有的的所有权限
     */
    @Override
    public List<String> getResourceByLoginAdmin(Integer userId) {

        StpInterface stpInterface = SaManager.getStpInterface();

        Object o = redisService.get(userId + ":" + RedisConstant.USER_RESOURCE);

        if (Opp.of(o).isEmpty()){

            //得到角色
            List<String> role = stpInterface.getRoleList(userId, null);

            List<Integer> list = Many.of(Role::getRoleName).in(role).value(Role::getId).query();

            Map<Integer, List<String>> query = OneToManyToOne.of(RoleResource::getRoleId).in(list).value(RoleResource::getResourceId)
                    .attachKey(Resource::getId)
                    .attachValue(Resource::getUrl).query();
            List<String> urlList = new ArrayList<>();
            query.forEach((k, v) -> urlList.addAll(v));
            redisService.set(userId + ":" + RedisConstant.USER_RESOURCE, JSONUtil.toJsonStr(urlList));
            //返回所拥有资源url
            return urlList;
        }else {

            return JSONUtil.toList(String.valueOf(o), String.class);
        }


    }

    @Override
    public List<Integer> getResourceIdByRoleId(Integer roleId) {


        return Many.of(RoleResource::getRoleId).eq(roleId).value(RoleResource::getRoleId).query();

    }


    @Override
    public void deleteResources(Integer roleId) {

        LambdaQueryWrapper<RoleResource> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleResource::getRoleId, roleId);

        if (list(queryWrapper).size() == 0){
            return;
        }

        LambdaUpdateWrapper<RoleResource> updateWrapper = new LambdaUpdateWrapper<>();

        updateWrapper.eq(RoleResource::getRoleId, roleId);

        remove(updateWrapper);
    }

    @Override
    public List<RoleResource> addRoleResource(Integer roleId, List<Integer> resourceIds) {

        List<RoleResource> roleResources = new ArrayList<>(resourceIds.size());

        resourceIds.forEach(roleResourceK -> {

            RoleResource roleResource = new RoleResource();

            roleResource.setRoleId(roleId);
            roleResource.setResourceId(roleResourceK);

            roleResources.add(roleResource);
        });

        saveBatch(roleResources);

        return roleResources;
    }
}
